#include "stdafx.h"
#include "QFramelessDialog.h"
#include "QIconHelper.hpp"

QFramelessDialog::QFramelessDialog(QWidget *parent)
	: QDialog(parent)
	, m_bMaximized(false)
	, m_bMoveable(false)
	, m_bResize(false)
	, m_menuButton_Close(nullptr)
	, m_menuButton_Max(nullptr)
	, m_menuButton_Min(nullptr)
	, m_widget_title(nullptr)
	, m_bMinClose(false)
{
/*	setAttribute(Qt::WA_TranslucentBackground);*/
	setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowMinMaxButtonsHint);
	setWindowModality(Qt::WindowModal);
	setFocusPolicy(Qt::ClickFocus);
}

QFramelessDialog::~QFramelessDialog()
{

}

void QFramelessDialog::Init(QWidget *widget_title, 
							QPushButton *menuButton_Close, 
							QPushButton *menuButton_Max,
							QPushButton *menuButton_Min,
							bool bResize,
							bool bMinClose,
							bool bConnectClose)
{
	m_bResize = bResize;
	m_bMinClose = bMinClose;
	m_bConnectClose = bConnectClose;
	m_menuButton_Min = menuButton_Min;
	m_menuButton_Max = menuButton_Max;
	m_menuButton_Close = menuButton_Close;
	m_widget_title = widget_title;
	
	if (m_menuButton_Close)
	{
		m_menuButton_Close->setFocusPolicy(Qt::ClickFocus);
		QIconHelper::SetIcon(m_menuButton_Close, QChar(0xf00d), 12);
		if (m_bMinClose)
		{
			if (m_bConnectClose)
			{
				connect(m_menuButton_Close, SIGNAL(clicked()), this, SLOT(hide()));
			}
		}
		else
		{
			connect(m_menuButton_Close, SIGNAL(clicked()), this, SLOT(sltCloseDialog()));
		}
	}
	if (m_menuButton_Max)
	{
		m_menuButton_Max->setFocusPolicy(Qt::ClickFocus);
		QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf096), 12);
		connect(m_menuButton_Max, SIGNAL(clicked()), this, SLOT(sltClickMaxRestore()));
	}
	if (m_menuButton_Min)
	{
		m_menuButton_Min->setFocusPolicy(Qt::ClickFocus);
		QIconHelper::SetIcon(m_menuButton_Min, QChar(0xf068), 12);
		connect(m_menuButton_Min, SIGNAL(clicked()), this, SLOT(sltClickMin()));
	}

	return;
}

void QFramelessDialog::CloseDialog()
{
	close();
}

void QFramelessDialog::sltCloseDialog()
{
	CloseDialog();
}

void QFramelessDialog::mousePressEvent(QMouseEvent *event)
{
	if (isFullScreen())
	{
		return;
	}

    if (event->button() == Qt::LeftButton && m_widget_title)
	{
		dragPosition = event->globalPos() - frameGeometry().topLeft();

		QRect rect = m_widget_title->rect();
		if (rect.contains(event->pos()))
		{
			m_bMoveable = true;
		}
	}
	event->accept();
}

void QFramelessDialog::mouseMoveEvent(QMouseEvent *event)
{
	if (isFullScreen())
	{
		return;
	}

	if (event->buttons() & Qt::LeftButton && m_bMoveable)
	{
		if (isMaximized())
		{
			int nWidth = m_rcNormal.width();
			int nHeight = m_rcNormal.height();

			float fx = (float)event->pos().x() / (float)rect().width();
			//屏幕大小
			int old_x = m_rcNormal.width() * fx + m_rcNormal.left();
			int old_y = m_rcNormal.top() + event->pos().y();

			QPoint pt_new(m_rcNormal.left() + event->globalPos().x() - old_x, m_rcNormal.top() + event->globalPos().y() - old_y);
			m_rcNormal.moveTopLeft(pt_new);
			sltClickMaxRestore();
			//m_rcNormal
			dragPosition = event->globalPos() - frameGeometry().topLeft();
		}
		else
		{
			move(event->globalPos() - dragPosition);
		}
	}
	event->accept();

}

void QFramelessDialog::mouseReleaseEvent(QMouseEvent *event)
{
	if (isFullScreen())
	{
		return;
	}
	if (m_bMoveable)
	{
		m_bMoveable = false;
	}
	event->accept();
}

void QFramelessDialog::mouseDoubleClickEvent(QMouseEvent *event)
{
	if (m_bResize == false)
	{
		return;
	}
	if (m_menuButton_Max == nullptr || m_menuButton_Min == nullptr)
	{
		return;
	}
	if (isFullScreen())
	{
		return;
	}
    if (event->buttons() & Qt::LeftButton && m_widget_title)
	{
		QRect rect = m_widget_title->rect();
		if (rect.contains(event->pos()))
		{
			sltClickMaxRestore();
		}
	}
	event->accept();
}

void QFramelessDialog::sltClickMin()
{
	showMinimized();
}

void QFramelessDialog::sltClickMaxRestore()
{
	if (isMaximized())
	{
		showNormal();
		setGeometry(m_rcNormal);
		qDebug() << m_rcNormal;

		QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf096), 10);
		m_menuButton_Max->setToolTip(QStringLiteral("最大化"));
	}
	else
	{
		m_rcNormal = geometry();
		showMaximized();

		QIconHelper::SetIcon(m_menuButton_Max, QChar(0xf079), 10);
		m_menuButton_Max->setToolTip(QStringLiteral("还原"));
	}
}

bool QFramelessDialog::nativeEvent(const QByteArray & eventType, void * message, long * result)
{
	Q_UNUSED(eventType);
	const int HIT_BORDER = 4;
	const MSG *msg = static_cast<MSG*>(message);

	if (msg->message == WM_NCCALCSIZE)
	{
		*result = 0;
		return true;
	}
	else if (msg->message == WM_NCHITTEST)
	{
		if (m_bResize == false || m_widget_title == nullptr)
		{
			return QDialog::nativeEvent(eventType, message, result);
		}

		if (isMaximized())
		{
			return false;
		}
		int xPos = ((int)(short)LOWORD(msg->lParam)) - this->frameGeometry().x();
		int yPos = ((int)(short)HIWORD(msg->lParam)) - this->frameGeometry().y();

		if (xPos >= 0 && xPos < HIT_BORDER && yPos >= 0 && yPos < HIT_BORDER) {
			*result = HTTOPLEFT;
			return true;
		}
		if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos > 0 && yPos < HIT_BORDER) {
			*result = HTTOPRIGHT;
			return true;
		}
		if (xPos > 0 && xPos < HIT_BORDER && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
			*result = HTBOTTOMLEFT;
			return true;
		}
		if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0) && yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
			*result = HTBOTTOMRIGHT;
			return true;
		}
		if (xPos >= 0 && xPos < HIT_BORDER) {
			*result = HTLEFT;
			return true;
		}
		if (xPos >(this->width() - HIT_BORDER) && xPos < (this->width() - 0)) {
			*result = HTRIGHT;
			return true;
		}
		if (yPos >= 0 && yPos < HIT_BORDER) {
			*result = HTTOP;
			return true;
		}
		if (yPos >(this->height() - HIT_BORDER) && yPos < (this->height() - 0)) {
			*result = HTBOTTOM;
			return true;
		}
		if (m_widget_title->geometry().contains(QPoint(xPos, yPos)))
		{
			*result = HTCAPTION;
			return false;
		}
		return false;
	}
	return false;
}

#define SHADOW_BORDER 6
void QFramelessDialog::paintEvent(QPaintEvent *event)
{
	return QDialog::paintEvent(event);
// 
// 	QPainterPath path;
// 	path.setFillRule(Qt::WindingFill);
// 	path.addRect(SHADOW_BORDER, SHADOW_BORDER, this->width()-2*SHADOW_BORDER, this->height()-2*SHADOW_BORDER);
// 
// 	QPainter painter(this);
// 	painter.setRenderHint(QPainter::Antialiasing, true);
// 	painter.fillPath(path, QBrush(Qt::white));
// 
// 	QColor color(0, 0, 0, 60);
// 	for(int i=0; i<SHADOW_BORDER; i++)
// 	{
// 		QPainterPath path;
// 		path.setFillRule(Qt::WindingFill);
// 		path.addRect(SHADOW_BORDER-1-i, SHADOW_BORDER-1-i, this->width()-(SHADOW_BORDER-i)*2, this->height()-(SHADOW_BORDER-i)*2);
// 		color.setAlpha(40 - i * 7);
// 		painter.setPen(color);
// 		painter.drawPath(path);
// 	}
}

void QFramelessDialog::keyPressEvent(QKeyEvent* e)
{
	qDebug()<<e->key();
	switch (e->key())
	{
	case Qt::Key_Return:
		break;
	case Qt::Key_Enter:
		break;
	case Qt::Key_Escape:
		{
			if (m_bMinClose)
				break;
		}
	default:
		QDialog::keyPressEvent(e);
	}
}

